package com.sunwhite.herostore.common;

import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.Message;
import com.sunwhite.herostore.msg.GameMsgProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * 消息识别处理器
 */
public class GameMsgRecognizer {
   private static final Logger logger= LoggerFactory.getLogger(GameMsgRecognizer.class);
    /**
     * 初始化msgCode
     */
    private static Map<Integer, GeneratedMessageV3> msgCodeBuilderMap=new HashMap<>();

    private static Map<Class<?>,Integer> msgClassMap=new HashMap<>();

    public static void init()  {
        //利用反射获取游戏消息下的所有子类
        //getDeclaredClasses 获取改类下的所有子类 返回calss数组
        Class<?>[] declaredClasses = GameMsgProtocol.class.getDeclaredClasses();
        for (Class<?> declaredClass : declaredClasses) {
            //isAssignableFrom 判断是否是calss的子类，包括这个类自身
            if (!GeneratedMessageV3.class.isAssignableFrom(declaredClass)){
                continue;
            }
            GameMsgProtocol.MsgCode[] values = GameMsgProtocol.MsgCode.values();
            //getSimpleName 获取简单类名
            String className = declaredClass.getSimpleName().toLowerCase();
            for (GameMsgProtocol.MsgCode msgCode : values) {
                if (!msgCode.name().replaceAll("_","").toLowerCase().startsWith(className)){
                   continue;
                }
                try {
                    //通过执行该calss的getDefaultInstance 方法（method）获取该类的实例
                    //invoke method通过反射执行方法
                    GeneratedMessageV3 getDefaultInstance =( GeneratedMessageV3) declaredClass.getDeclaredMethod("getDefaultInstance").invoke(declaredClass);
                    msgCodeBuilderMap.put(msgCode.getNumber(),getDefaultInstance);
                    msgClassMap.put(declaredClass,msgCode.getNumber());
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error(e.getMessage(),e);
                }
            }
        }

    }

    public static Message.Builder getBuilderByMsgCode(int msgCode){
        if (msgCode<0){
            return null;
        }
        GeneratedMessageV3 builder = msgCodeBuilderMap.get(msgCode);
        if (null!=builder){
            return builder.newBuilderForType();
        }
        return null;
    }

    public static int getMsgCodeByMsgClass(Class<?> tClass){
        if (tClass==null){
            return -1;
        }
        Integer integer = msgClassMap.get(tClass);
        if (integer!=null){
            return integer.intValue();
        }
        return -1;
    }
}
